<template>
	<div class="select-filter">
		<div v-for="item in data" :key="item.key" class="select-filter-item">
			<div class="select-filter-item-title">
				<span>{{ item.title }} ：</span>
			</div>
			<span v-if="!item.options.length" class="select-filter-notData">暂无数据 ~</span>
			<el-scrollbar>
				<ul class="select-filter-list">
					<li
						v-for="option in item.options"
						:key="option.value"
						:class="{
							active:
								option.value === selected[item.key] ||
								(Array.isArray(selected[item.key]) && selected[item.key].includes(option.value))
						}"
						@click="select(item, option)"
					>
						<slot :row="option">
							<el-icon v-if="option.icon"><component :is="option.icon" /></el-icon>
							<span>{{ option.label }}</span>
						</slot>
					</li>
				</ul>
			</el-scrollbar>
		</div>
	</div>
</template>

<script setup lang="ts" name="selectFilter">
import { ref, watch } from "vue";

interface OptionsProps {
	value: string | number;
	label: string;
	icon?: string;
}

interface SelectDataProps {
	title: string; // 列表标题
	key: string; // 当前筛选项 key 值
	multiple?: boolean; // 是否为多选
	options: OptionsProps[]; // 筛选数据
}

interface SelectFilterProps {
	data?: SelectDataProps[]; // 选择的列表数据
	defaultValues?: { [key: string]: any }; // 默认值
}

const props = withDefaults(defineProps<SelectFilterProps>(), {
	data: () => [],
	defaultValues: () => ({})
});

// 重新接收默认值
const selected = ref<{ [key: string]: any }>({});
watch(
	() => props.defaultValues,
	() => {
		props.data.forEach(item => {
			if (item.multiple) selected.value[item.key] = props.defaultValues[item.key] ?? [""];
			else selected.value[item.key] = props.defaultValues[item.key] ?? "";
		});
	},
	{ deep: true, immediate: true }
);

interface FilterEmits {
	(e: "change", value: any): void;
}
const emit = defineEmits<FilterEmits>();

/**
 * @description 选择筛选项
 * @param {Object} item 选中的哪项列表
 * @param {Object} option 选中的值
 * @return void
 * */
const select = (item: SelectDataProps, option: OptionsProps) => {
	if (!item.multiple) {
		// * 单选
		if (selected.value[item.key] !== option.value) selected.value[item.key] = option.value;
	} else {
		// * 多选
		// 如果选中的是第一个值，则直接设置
		if (item.options[0].value === option.value) selected.value[item.key] = [option.value];
		// 如果选择的值已经选中了，则删除选中的值
		if (selected.value[item.key].includes(option.value)) {
			let currentIndex = selected.value[item.key].findIndex((s: any) => s === option.value);
			selected.value[item.key].splice(currentIndex, 1);
			// 当全部删光时，把第第一个值选中
			if (selected.value[item.key].length == 0) selected.value[item.key] = [item.options[0].value];
		} else {
			// 未选中点击值的时候，追加选中值
			selected.value[item.key].push(option.value);
			// 单选中全部并且点击到了未选中的值，把第一个值删除掉
			if (selected.value[item.key].includes(item.options[0].value)) selected.value[item.key].splice(0, 1);
		}
	}
	emit("change", selected.value);
};
</script>

<style scoped lang="scss">
@import "./index.scss";
</style>
